import arrow
import requests
from flask import Blueprint,request,redirect,make_response,Response
from application.models.model import *
from cache import my_cache
from swaager_init import siwa,BaseModel
from db_init import db
from sqlalchemy.exc import IntegrityError
from tools.broker_api import get_token_by_code, get_warrant_url
from tools.data_tools import orm2dict,ret_route,limit_framt
from flask_login import login_user,login_required,current_user
from captcha.image import ImageCaptcha
import re,redis,random,string,arrow
from cache import my_cache
from config import VIP_EBD_TIME, LOGIN_APP_MAP
from threading import Thread
from application.celery_my.send_mobile_code import send_one_code
from copy import copy,deepcopy


user_blue = siwa.blueprint("userblue", __name__)

class Begrister(BaseModel):
    mobile:int
    password:str
    nikename:str

@user_blue.route("/reg",methods=['post'])
def reg():
    ud = dict(Begrister(**request.json))
    uuid = request.args.get('uuid')
    imgcode = ud.pop('imgcode')

    broker = ud.pop('broker') if 'broker' in ud else None
    broker_uid = ud.pop('broker_uid') if 'broker_uid' in ud else None

    # 校验
    # 从redis中取出数据，如果没有数据就是报错notype
    code = my_cache.get(uuid)
    my_cache.delete(uuid)
    # 判断条件是否满足
    if not code or imgcode.lower() != code.decode():
        return ret_route(402)
    try:
        user = User(**ud)
        db.session.add(user)
        # 清空缓存，提交
        db.session.flush()

        if broker and broker_uid:
            bu = BrokerUser(broker_name=broker,broker_uid=broker_uid)
            db.session.add(bu)

        db.session.commit()

        return {'code':200,'msg':'注册成功','data':{'user_id':user.id}}
    except IntegrityError as e:
        print(e)
        return {'code':400,'msg':'账号已经存在哎'}

@user_blue.route('/login',methods=['post'])
def login():
    user_data = request.json
    user = User.query.filter_by(**user_data).first()
    if user:
        login_user(user)
        return {'code':200,'msg':'登录成功','data':orm2dict(user)}
    return {'code':403,'msg':'请输入正确的账号密码'}

@user_blue.route('/imgcode',methods=['get'])
def imgcode():
    # 生成验证码
    # 验证码图片
    # 验证码存放redis
    # 把图片返回
    uuid = request.args.get('uuid')
    img_string = ''.join(random.sample(string.digits + string.ascii_letters, 4))
    img = ImageCaptcha()
    # 转换成图片
    img_code = img.generate(img_string)
    # 写入redis
    my_cache.set(name=uuid,value=img_string.lower(),ex=300)
    return ret_route(data=Response(img_code,mimetype='img/png'))

# 获取短信验证码
@user_blue.route('/sms_code',methods=['get'])
def message():
    mobile = request.args.get('mobile')
    if not mobile:
        return ret_route(403)
    if not re.findall(r'^1[3-9]\d{9}$',mobile):
        return ret_route(409)
    Thread(target=send_one_code,args=(mobile,)).start()
    return ret_route(200)

# 添加角色的vip
@user_blue.route('/vip',methods=['post'])
@login_required
def buy_vip():
    role_id = request.json.get('role_id')
    end_t = arrow.now().int_timestamp + VIP_EBD_TIME
    current_user.vip = 1
    current_user.end_t = end_t
    current_user.role.append(Role.query.get(role_id))
    # 存入缓存中
    db.session.flush()
    db.session.query(role_user).filter_by(role_id=role_id,user_id=current_user.id).update({'end_t':end_t})
    db.session.commit()
    return ret_route(200)

# 登录微博
# @user_blue.route('/login/wb',methods=['get'])
# def login_wb():
#     weibo_api = f"https://api.weibo.com/oauth2/authorize?client_id={LOGIN_APP_MAP['weibo']['client_id']}" \
#                 f"&redirect_url={LOGIN_APP_MAP['weibo']['redirect_url']}"
#     return ret_route(302,data=weibo_api)

@user_blue.route("/login/<any(weibo,github,gitee):broker>", methods=['GET'])
def broker_login(broker):
    return ret_route(302, data=get_warrant_url(broker))

# 二维码登录
@user_blue.route("/weiboCallback/", methods=['get'])
def weibo_callback():
    code = request.args.get('code')
    params = f'code={code}'
    for k, v in LOGIN_APP_MAP['weibo'].items():
        params += f"&{k}={v}"
    weibo_api = f"https://api.weibo.com/oauth2/access_token?{params}"
    ret = requests.post(weibo_api, headers={'Accept': 'application/json'})
    retdata = ret.json()
    print(retdata)
    BrokerUser.query.filter_by(broker_uid=retdata['uid'], broker_name='weibo').first()
    return ret_route(302, data=weibo_api)

# Vip过期时间数据复位
@user_blue.route('/update_vip',methods=['put'])
@login_required
def put_user_vip():
    # 前端接收参数
    id = request.args.get('u_id')
    # 筛选出要查询的用户
    user = User.query.filter(User.id == id).first()
    # 判断用户的vip状态
    # 如果用户此时还是vip,判断用户的vip时间是否快过期
    if user.vip == 1:
        # 直接从flask_login中获取用户的登录状态,货期其中的所有信息,用户的结束时间重新赋值
        user_endtime = current_user.end_t
        # 从角色中查出所对应的角色的vip过期时间
        user_data = User.query.filter(Role.end_t <= user_endtime)
        if user_data:
            User.query.filter(User.id == id ).update({'vip':User.vip == 0})
            db.session.commit()
    return ret_route(200)

@user_blue.route("/login", methods=['get'])
def test_login():
    uid = request.args.get('uid')
    user = User.query.get(uid)
    login_user(user)
    return {"code": 200, 'msg': '登录成功'}




